package com.fyz.aaronfjava.util;

import com.fyz.aaronfjava.model.response.HttpResponse;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.StatusLine;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @Author：fanyaozhou
 * @Date：2023/12/19 14:40
 * @description http请求工具类
 */
public class HttpUtil {

    private static final Logger log = LoggerFactory.getLogger(HttpUtil.class);


    /**
     * 发起get请求 默认超时时间为5s
     * @param url 请求url
     * @return
     */
    public static HttpResponse doGet(String url) {
        return doGet(url,null,null,5000);
    }

    /**
     * 发起get请求 默认超时时间为5s
     * @param url 请求url
     * @param params 请求参数 拼接到url后面
     * @return
     */
    public static HttpResponse doGet(String url, Object params,Map<String,String> headers) {
        return doGet(url,params,headers,5000);
    }

    /**
     * 发起get请求
     * @param url 请求url
     * @param params 请求参数 拼接到url后面
     * @param timeOut 超时时间
     * @return
     */
    public static HttpResponse doGet(String url, Object params,Map<String,String> headers,int timeOut) {
        headers = Optional.ofNullable(headers).orElse(new HashMap<>());
        //拼接请求参数
        url += StringUtil.buildGetRequestStr(params);
        // 创建httpGet实例
        HttpGet httpGet = new HttpGet(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeOut)
                .setConnectionRequestTimeout(timeOut)
                // 超时参数 毫秒级别
                .setSocketTimeout(timeOut)
                .build();
        httpGet.setConfig(requestConfig);
        log.info("发起http get请求，请求路径{}",url);
        return execute(httpGet,headers);
    }

    /**
     * 发起post请求 默认超时时间为5s
     * @param url 请求url
     * @return
     */
    public static HttpResponse doPost(String url) {
        return doPost(url,StringUtil.BLANK,null,5000);
    }

    /**
     * 发起post请求 默认超时时间为5s
     * @param url 请求url
     * @param params 请求体 要求为json格式
     * @return
     */
    public static HttpResponse doPost(String url, String params,Map<String,String> headers) {
        return doPost(url,params,headers,5000);
    }

    /**
     * 发起post请求
     * @param url 请求url
     * @param params 请求体 要求为json格式
     * @param timeOut 超时时间
     * @return
     */
    public static HttpResponse doPost(String url, String params,Map<String,String> headers, int timeOut) {
        headers = Optional.ofNullable(headers).orElse(new HashMap<>());
        // 创建httpPost实例
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeOut)
                .setConnectionRequestTimeout(timeOut)
                // 超时参数 毫秒级别
                .setSocketTimeout(timeOut)
                .build();
        httpPost.setConfig(requestConfig);
        // 设置content-type为json格式
        headers.put(HttpHeaders.CONTENT_TYPE,ContentType.APPLICATION_JSON.getMimeType());
        // 设置请求体
        HttpEntity httpEntity = new StringEntity(params, ContentType.APPLICATION_JSON);
        httpPost.setEntity(httpEntity);
        log.info("发起http post请求，请求路径{}，请求参数{}",url,params);
        return execute(httpPost,headers);
    }

    /**
     * 发起http请求
     * @param request 请求对象
     * @return
     */
    private static HttpResponse execute(HttpUriRequest request,Map<String,String> headers) {
        //注入请求头
        detailHeader(request,headers);
        try(// 创建httpClient实例
            CloseableHttpClient httpClient = HttpClients.createDefault();
            // httpClient对象执行请求,并返回响应参数对象
            CloseableHttpResponse httpResponse = httpClient.execute(request)){
            // 获取响应码
            StatusLine statusLine = httpResponse.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            String content = "";
            if (entity != null) {
                content = EntityUtils.toString(entity, "UTF-8");
            }
            return new HttpResponse(statusCode, content);
        } catch (IOException e) {
            String msg = request.getURI() + "调用异常，错误信息：" + e.getMessage();
            throw new RuntimeException(msg);
        }
    }

    private static void detailHeader(HttpUriRequest request,Map<String,String> headers){
        if (headers == null || headers.isEmpty()){
            return;
        }
        //注入请求头
        headers.keySet().forEach(head -> request.setHeader(head,headers.get(head)));
    }

}
